/*********************************************************************
 * S5 - C++ Básico
 * Autor: Felipe Perea Toledo
 *
 *
 * Lee el contenido de un archivo de texto, cuyo nombre se pase como parámetro,
 * y genera otro archivo de texto con la siguiente información relativa al primer archivo:
 *
 * Nombre: <nombre_archivo_entrada>
 * Tamanyo: <tamaño_bytes_archivo_entrada>
 * Nº líneas: <número_líneas_archivo_entrada>
 * Nº palabras palíndromo: <número_palabras_palíndromo>
 *********************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <sstream>
#include <sys/stat.h>

namespace {
/**
 * Constantes
 */
	const char* EL_FICHERO_INTRODUCIDO_NO_EXISTE = "El fichero introducido no existe";
	const char* ERROR_AL_ABRIR_EL_FICHERO_DE_ENTRADA = "Error al abrir el fichero de entrada";
	const char* ERROR_AL_ABRIR_EL_FICHERO_DE_SALIDA = "Error al abrir el fichero de salida";
	const char* FICHERO_SALIDA_YA_EXISTE = "El fichero de salida ya existe, desea sobreescribirlo? (S/N) ";
	const char* SOLICITUD_FICHERO_DE_SALIDA = "Introduzca un nombre de fichero de salida:  ";
	const char* SOLICITUD_FICHERO_DE_ENTRADA = "Introduzca un nombre de fichero de entrada:  ";
	const char* N_PALINDROMAS = "Nº palabras palíndromas: ";
	const char* N_LINEAS = "Nº líneas: ";
	const char* BYTES = " bytes";
	const char* TAMANYO = "Tamanyo: ";
	const char* NOMBRE = "Nombre: ";
	const char* SI_LOWER = "s";
	const char* SI = "S";
}

using namespace std;

/**
 * Constantes
 */
/**
 * Comprueba si un fichero cuyo nombre se recibe ya existe
 */
bool fileExists(const string& filename)
{
    struct stat buf;
    if (stat(filename.c_str(), &buf) != -1)
    {
        return true;
    }
    return false;
}

/**
 * Comprueba si la palabra recibida es palíndroma
 */
bool isPalindromo(const string& word)
{
	bool bPalindromo = true;
	int i,j,len = word.length();

	for (i = 0, j = len - 1; i <= (len / 2) && bPalindromo;
			++i, --j) {
		if (word[i] != word[j]) {
			bPalindromo = false;
		}
	}
    return bPalindromo;
}

/**
 * Recupera el tamaño del fichero que se le pasa
 */
long tamannoFichero (ifstream& file) {
	long beginFile, endFile;

	// Tamaño del fichero
	beginFile = file.tellg();
	file.seekg(0, ios::end);
	endFile = file.tellg();

	// Nos posicionamos de nuevo al inicio del fichero de entrada
	file.seekg(0, ios::beg);

	return endFile - beginFile;
}

/**
 * Main
 */
int main(void) {
	ofstream myFileOut;
	ifstream myFileIn;
	string line, sFicheroIn, sFicheroOut, sSobreescribir;
	int numLineas = 0, numPalindromos = 0;

	/**
	 * Solicitud del fichero de entrada
	 */
	cout << SOLICITUD_FICHERO_DE_ENTRADA;
	cin >> sFicheroIn;

	// Comprobamos si el fichero de entrada existe
	if (fileExists(sFicheroIn)){
		// Abrimos el fichero de entrada
		myFileIn.open(sFicheroIn.c_str());

		/**
		 * Solicitud del fichero de salida
		 */
		cout << SOLICITUD_FICHERO_DE_SALIDA;
		cin >> sFicheroOut;

		// Si hemos conseguido abrir el fichero de entrada
		if (myFileIn.is_open()) {

			bool continuar = true;

			// Comprobamos que el fichero de salida ya exista
			if (fileExists(sFicheroOut)){
				cout << FICHERO_SALIDA_YA_EXISTE;
				cin >> sSobreescribir;

				if (sSobreescribir != SI && sSobreescribir != SI_LOWER) {
					continuar = false;
				}
			}

			// Si el fichero de salida no existía o si hemos decidido sobreescribirlo
			if (continuar) {

				// Intentamos abrir el fichero de salida
				myFileOut.open(sFicheroOut.c_str());

				if (myFileOut.is_open()) {

					// Nombre del fichero
					myFileOut << NOMBRE << sFicheroIn << endl;

					// Tamaño del fichero
					myFileOut << TAMANYO << tamannoFichero(myFileIn) << BYTES << endl;

					int numPalabras = 0;

					// Recorremos las líneas del fichero de entrada
					while (getline(myFileIn, line)) {

						// Incrementamos el número de líneas
						numLineas++;

						// Recorremos las palabras de la línea para comprobar las palíndromas
						string word;
						istringstream ss(line);
						while (ss >> word) {
							// Si la línea era palíndroma incrementamos el contador
							if (isPalindromo(word)) {
								numPalindromos++;
							}
						}
					}

					// Número de líneas
					myFileOut << N_LINEAS << numLineas << endl;

					// Número de palíndromos
					myFileOut << N_PALINDROMAS << numPalindromos << endl;

					myFileOut.close();

				} else {
					cout << ERROR_AL_ABRIR_EL_FICHERO_DE_SALIDA << endl;
				}

			}

			myFileIn.close();
		}

		else {
			cout << ERROR_AL_ABRIR_EL_FICHERO_DE_ENTRADA << endl;
		}

	} else {
		cout << EL_FICHERO_INTRODUCIDO_NO_EXISTE << endl;
	}

	return 0;
}
